package com.biqee.service.crawler.impl;

import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import com.biqee.constant.SystemConstant;
import com.biqee.exception.BusinessUnCheckedException;
import com.biqee.exception.ErrorCode;
import com.biqee.service.crawler.BqIndexBuilder;
import com.biqee.util.DateUtil;
import com.biqee.util.EnvUtil;
import com.biqee.util.HttpUtil;
import com.biqee.util.JsoupUtil;
import com.biqee.util.StoreUtil;
import com.biqee.util.StringUtil;

class BqIndexBuilderImpl implements BqIndexBuilder {
	private static Logger LOG = Logger.getLogger(BqIndexBuilderImpl.class);

	private static int max_level = 1;
	private String pathRoot = "/hishtml/";
	
	private String todayRoot = pathRoot+"today/";
	
	
	private Map<String,String> hasLinksMap = new HashMap<String,String>();

	@Override
	public void build(String url) {
		try {
			backup( null) ;
		} catch (IOException e) {
			throw new BusinessUnCheckedException(ErrorCode.INDEX_FETCH_002, e);
		}
		build(url, 0, 0);
	}

	public void backup(String folderName) throws IOException {
		String destDir = null;
		if(StringUtil.isBlank(folderName)){
			 destDir =  StoreUtil.STORE_ROOT+pathRoot+getPreDay();
		}else{
			destDir = StoreUtil.STORE_ROOT+pathRoot+folderName;
		}
		String folder = StoreUtil.STORE_ROOT+todayRoot;
		File root = new File(folder);
		if(root.isDirectory()){
			File destFile = new File(destDir);
			if(destFile.exists()){
				FileUtils.forceDelete(destFile);
			}
			FileUtils.moveDirectory(root, destFile);
		}
		
	}

	private String build(String url, int index, int deep) {
	
		
		if(hasLinksMap.containsKey(url)){
			return hasLinksMap.get(url);
		}
		if (deep > max_level) {
			return null;
		}
		LOG.info("fetch htm url="+url);
		String name =null;
		String html = null;
		
		if (index == 0 && deep == 0) {
			name = "index.html";
		} else {
			name = + deep + "_" + index + ".html";
		}
		hasLinksMap.put(url,name);
		deep++;
		Map<String,String> linkMap = new HashMap<String,String>();
		try {
			html = HttpUtil.getHttpResponse(url,
					SystemConstant.DEFAULT_CHARTSET);
		} catch (IOException e) {
			LOG.error("get url error,url=" + url, e);
			throw new BusinessUnCheckedException(ErrorCode.INDEX_FETCH_001);
		}
		Document doc = JsoupUtil.createDocument(html);
		validate(doc);
		Elements elements = doc.getElementsByAttributeValueContaining("href",
				"jspa");
		Set<String> urlSet = new HashSet<String>();
		if (elements != null) {
			String prifixUrl = url.substring(0, url.lastIndexOf("/")+1);
			String rootUrl = EnvUtil.getWebUrl();
			for (Element element : elements) {

				String a = element.attr("href");
				String realUrl = null;
				if (StringUtil.isNotBlank(a)) {
					if (ValidateUrl(a) == false) {
						if (a.startsWith("/")) {
							realUrl = rootUrl + a;
						} else {
							realUrl = prifixUrl + a;
						}
					}else{
						realUrl =a ;
					}				
					urlSet.add(realUrl);
					linkMap.put(realUrl, a);
				}
			}
		}
		
		
		if (!urlSet.isEmpty()) {
			int i = 0;
			for (String subUrl : urlSet) {
				i++;
				String newLink = build(subUrl, i, deep);
				String oldLink =linkMap.get(subUrl);
				if (newLink != null) {
					html = StringUtil.replace(html, oldLink, newLink);
				}else{
					html = StringUtil.replace(html, oldLink, subUrl);
				}
			}
		}
		String storePath = todayRoot+name;
		try {
			StoreUtil.storeFile(storePath, html, SystemConstant.DEFAULT_CHARTSET);
		} catch (IOException e) {
			throw new BusinessUnCheckedException(ErrorCode.INDEX_FETCH_002);
		}
		LOG.info("fetch htm url="+url+",store path"+pathRoot+storePath);
		return name;
	}

	private boolean ValidateUrl(String link) {
		if (link.startsWith("http://") || link.startsWith("https://")) {
			return true;
		} else {
			return false;
		}

	}

	private void validate(Document doc) {
		// TODO Auto-generated method stub

	}
	
	
	private String getPreDay(){
		Date date= DateUtil.getPrevDay(new Date());
		return DateUtil.formatYYYYMMDD(date);
	}
}
